package ece1779.ec2;

import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.sql.DataSource;

import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.*;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.Vector;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClient;
import com.amazonaws.services.cloudwatch.model.Datapoint;
import com.amazonaws.services.cloudwatch.model.DescribeAlarmsRequest;
import com.amazonaws.services.cloudwatch.model.DescribeAlarmsResult;
import com.amazonaws.services.cloudwatch.model.Dimension;
import com.amazonaws.services.cloudwatch.model.DimensionFilter;
import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsRequest;
import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsResult;
import com.amazonaws.services.cloudwatch.model.ListMetricsRequest;
import com.amazonaws.services.cloudwatch.model.ListMetricsResult;
import com.amazonaws.services.cloudwatch.model.Metric;
import com.amazonaws.services.cloudwatch.model.MetricAlarm;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;

import org.im4java.core.*;


public class AlarmStatus extends HttpServlet {
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
	throws IOException, ServletException {
		doPost( request,  response);
	}
	
    public void doPost(HttpServletRequest request, HttpServletResponse response)
	throws IOException, ServletException {
        try {
        	
            PrintWriter out = response.getWriter();
            BasicAWSCredentials awsCredentials = (BasicAWSCredentials) getServletContext().getAttribute("AWSCredentials");
        	response.setContentType("text/html");
        	
        	Config config = new Config(awsCredentials, out, getServletContext().getRealPath("/"));
            double cpuUsage = getCpuAvg(out, "ami-34ff2d5d");
            
            if(cpuUsage > config.data.growTreshold){
            	InstanceManager.startInstances(awsCredentials, config.data.growMultiplier, out);
            	out.write(cpuUsage + " over " + config.data.growTreshold);
            }
            else if (cpuUsage < config.data.shrinkTreshold){
            	InstanceManager.stopInstances(awsCredentials, config.data.shrinkMultiplier, out);
            	out.write(cpuUsage + " under " + config.data.shrinkTreshold);
            }
            else {
            	out.write(cpuUsage + " ok");
            }
        }
        catch (Exception ex) {
		    throw new ServletException (ex);
		}
    }
    
    private double getCpuAvg(PrintWriter out, String imageID) throws IOException {
    	
    	
    	BasicAWSCredentials awsCredentials = (BasicAWSCredentials)getServletContext().getAttribute("AWSCredentials");
        AmazonCloudWatch cw = new AmazonCloudWatchClient(awsCredentials);
        
        try {
        	List<DimensionFilter>  dimFilter = new ArrayList<DimensionFilter>();
        	dimFilter.add(new DimensionFilter().withName("ImageId").withValue(imageID));
        	
        	ListMetricsRequest listMetricsRequest = new ListMetricsRequest();
        	listMetricsRequest.setMetricName("CPUUtilization");
        	listMetricsRequest.setNamespace("AWS/EC2");
        	listMetricsRequest.setDimensions(dimFilter);
        	
        	ListMetricsResult result = cw.listMetrics(listMetricsRequest);
        	java.util.List<Metric> 	metrics = result.getMetrics();
        	for (Metric metric : metrics) {
        		String namespace = metric.getNamespace();
        		String metricName = metric.getMetricName();
        		List<Dimension> dimensions = metric.getDimensions();
            	GetMetricStatisticsRequest statisticsRequest = new GetMetricStatisticsRequest();
            	statisticsRequest.setNamespace(namespace);
            	statisticsRequest.setMetricName(metricName);
            	statisticsRequest.setDimensions(dimensions);
            	Date endTime = new Date();
            	Date startTime = new Date();
            	startTime.setTime(endTime.getTime()-1200000);
            	statisticsRequest.setStartTime(startTime);
            	statisticsRequest.setEndTime(endTime);
            	statisticsRequest.setPeriod(60);
            	Vector<String>statistics = new Vector<String>();
            	statistics.add("Maximum");
            	statisticsRequest.setStatistics(statistics);
            	GetMetricStatisticsResult stats = cw.getMetricStatistics(statisticsRequest);
            	
            	
            	
            	List<Datapoint> dataPoints = stats.getDatapoints();
            	Date latest = new Date(0);
            	Datapoint latestPoint = null;
            	for (Datapoint dataPoint : dataPoints){
            		if (dataPoint.getTimestamp().after(latest)){
            			latest = dataPoint.getTimestamp();
            			latestPoint = dataPoint;
            		}
            	}
            	
            	return latestPoint.getMaximum();
        	}
			
        	
        } catch (AmazonServiceException ase) {
            out.println("Caught an AmazonServiceException, which means your request made it "
                    + "to Amazon EC2, but was rejected with an error response for some reason.");
            out.println("Error Message:    " + ase.getMessage());
            out.println("HTTP Status Code: " + ase.getStatusCode());
            out.println("AWS Error Code:   " + ase.getErrorCode());
            out.println("Error Type:       " + ase.getErrorType());
            out.println("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            out.println("Caught an AmazonClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with EC2, "
                    + "such as not being able to access the network.");
            out.println("Error Message: " + ace.getMessage());
        }
        
		return 0;
    }
    

    
}
